package cn.stylefeng.guns.modular.history.controller;
import org.apache.commons.net.util.SubnetUtils;
import org.springframework.util.StringUtils;

import cn.hutool.core.collection.CollectionUtil;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class IpValidatorUtil {
    
    /**
     * 统一白名单校验入口
     * @param clientIp 待校验IP
     * @param mixedWhitelist 混合白名单配置（支持IP/CIDR/通配符）
     * @return 是否允许访问
     */
    public static boolean checkIpAccess(String clientIp, List<String> mixedWhitelist) {
        return mixedWhitelist.stream()
                .anyMatch(entry -> isMatch(clientIp, entry));
    }

    /**
     * 单条规则匹配逻辑
     */
    private static boolean isMatch(String clientIp, String rule) {
        // 1. 处理具体IP
        if (isConcreteIp(rule)) {
            return clientIp.equals(rule);
        }
        
        // 2. 处理CIDR或通配符
        return checkNetwork(clientIp, rule);
    }

    /**
     * 判断是否为具体IP（非CIDR/通配符）
     */
    private static boolean isConcreteIp(String rule) {
        return !rule.contains("/") && !rule.contains("*");
    }

    /**
     * 网段校验（自动处理CIDR和通配符）
     */
    private static boolean checkNetwork(String ip, String network) {
        try {
            String cidr = network.contains("*") ? 
                convertWildcardToCidr(network) : network;
            
            SubnetUtils utils = new SubnetUtils(cidr);
            utils.setInclusiveHostCount(true);
            return utils.getInfo().isInRange(ip);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("无效的网段格式: " + network, e);
        }
    }

    /**
     * 通配符转CIDR（如 10.10.*.* → 10.10.0.0/16）
     * 10.*.*.* 标准CIDR格式（如 10.0.0.0/8）
     */
    private static String convertWildcardToCidr(String wildcard) {
        String[] parts = wildcard.split("\\.");
        if (parts.length > 4) {
            throw new IllegalArgumentException("Invalid IP format: " + wildcard);
        }

        // 补全4段
        String[] filled = Arrays.copyOf(parts, 4);
        Arrays.fill(filled, parts.length, 4, "*");

        // 找到第一个通配符位置
        int firstWildcardIndex = -1;
        for (int i = 0; i < 4; i++) {
            if ("*".equals(filled[i])) {
                firstWildcardIndex = i;
                break;
            }
        }

        // 无通配符时视为具体IP
        if (firstWildcardIndex == -1) {
            return wildcard + "/32";
        }

        // 校验通配符必须连续在末尾
        for (int i = firstWildcardIndex; i < 4; i++) {
            if (!"*".equals(filled[i])) {
                throw new IllegalArgumentException("通配符必须连续出现在末尾: " + wildcard);
            }
        }

        // 计算掩码位数
        int maskBits = firstWildcardIndex * 8;

        // 构造CIDR地址
        StringBuilder cidrIp = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            cidrIp.append(i < firstWildcardIndex ? filled[i] : "0");
            if (i < 3) cidrIp.append(".");
        }

        return cidrIp.append("/").append(maskBits).toString();
    }
    public static void main(String[] args) {
        String ips = "192.168.1.100,10.11.*.*,172.16.0.*";
        String[] ipsA = ips.split(",");
        List<String> whitelist = CollectionUtil.list(true, ipsA);
        
        System.out.println(IpValidatorUtil.checkIpAccess("10.10.5.20", whitelist)); // true
        System.out.println(IpValidatorUtil.checkIpAccess("192.168.1.100", whitelist)); // true
        System.out.println(IpValidatorUtil.checkIpAccess("10.11.1.1", whitelist));   // false
    }
}
